package com.browsesoft.baseadapter;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.browsesoft.SequenceFind;
import com.browsesoft.dbtools.ConnectionPool;
import com.browsesoft.dbtools.DBTools;
import com.browsesoft.tools.TempFileFactory;
import com.browsesoft.util.StreamHelper;

public class MysqlBlobEntity implements BlobEntity {

	/**
	 * id
	 */
	private String id;

	/**
	 * blob对象
	 */
	private Blob blob;

	/**
	 * 临时文件，存放要保存的内容
	 */
	private File file;

	/**
	 * 对应的文件输出流
	 */
	private OutputStream output;

	private static String tableName = "t_blob_entity";

	public MysqlBlobEntity() {
		try {
			this.file = TempFileFactory.getInstance().getFile();
			this.id = SequenceFind.getID() + "";
			this.output = new FileOutputStream(file);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	public MysqlBlobEntity(String id) {
		try {
			this.blob = this.getBlob(id);
		} catch (BLobObjectNotFoundException e) {
			throw new RuntimeException(e);
		}
	}

	private Blob getBlob(String id) throws BLobObjectNotFoundException {
		PreparedStatement pst = null;
		ResultSet rs = null;
		Connection connection = null;
		try {
			connection = ConnectionPool.createTempConnection();
			connection.setAutoCommit(false);
			pst = (PreparedStatement) connection
					.prepareStatement("select content from t_blob_entity where id=?");
			pst.setString(1, id);
			rs = pst.executeQuery();
			if (!rs.next()) {
				throw new BLobObjectNotFoundException();
			}
			blob = (Blob) rs.getBlob(1);
			return blob;
		} catch (SQLException ex) {
			throw new RuntimeException(ex);
		} finally {
			if (rs != null) {
				try {
					rs.close();
				} catch (SQLException e) {
				}
			}
			if (pst != null) {
				try {
					pst.close();
				} catch (SQLException e) {
				}
			}
			if (connection != null) {
				try {
					connection.close();
				} catch (SQLException e) {
				}
			}
		}
	}

	public void save() throws Exception {
		this.output.close();
		String insertSql = "insert into " + tableName + " values('" + id
				+ "', ?)";
		Connection connection = ConnectionPool.createTempConnection();
		PreparedStatement preparedStatement = connection
				.prepareStatement(insertSql);
		FileInputStream input = new FileInputStream(file);
		preparedStatement.setBinaryStream(1, input, (int) file.length());
		preparedStatement.executeUpdate();
		preparedStatement.close();
		try {
			connection.close();
		} catch (SQLException e) {
		} finally {
			TempFileFactory.getInstance().put(this.file);
		}
	}

	public void delete() throws Exception {
		// 从数据库中删除
		DBTools.delete(tableName, id);
	}

	public void saveOrUpdate(byte[] fileBody) {
		try {
			OutputStream outStream = this.getOutputStream();
			outStream.write(fileBody);
			this.save();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	public OutputStream getOutputStream() throws Exception {
		return this.output;
	}

	public InputStream getInputStream() throws Exception {
		return blob.getBinaryStream();
	}

	public String getContent() {
		InputStream is = null;
		try {
			is = this.getInputStream();
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
		String result = "";
		try {
			result = StreamHelper.getString(is);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException("读取大字断内容时失败", e);
		}
		return result;
	}

	public String getID() {
		return this.id;
	}

	public void close() {
		try {
			if (this.output != null) {
				this.output.close();
			}
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			TempFileFactory.getInstance().put(this.file);
		}
	}

	public long getLength() {
		try {
			return blob.length();
		} catch (SQLException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}
}
